home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-05
/
pcrte224.zip
/
SOURCE.ZIP
/
ETHER.INC
< prev
next >
Wrap
Text File
|
1992-06-09
|
10KB
|
283 lines
;;*****************************************************************************
;; ether.inc ether.inc
;;*****************************************************************************
;;
;; Copyright (C) 1989 Northwestern University, Vance Morrison
;;
;;
;; Permission to view, compile, and modify for LOCAL (intra-organization)
;; USE ONLY is hereby granted, provided that this copyright and permission
;; notice appear on all copies. Any other use by permission only.
;;
;; Northwestern University makes no representations about the suitability
;; of this software for any purpose. It is provided "as is" without expressed
;; or implied warranty. See the copywrite notice file for complete details.
;;
;;*****************************************************************************
;;
;; ether.inc constains the board independant, ethernet processing that needs
;; to be done. I rely only on the IF interface defined in if.inc.
;;
;; The functions provided by this file are
;;
;; ETH_DECLARE name, interface, task
;; ETH_DEFINE name
;; ETH_R_READ name, type, code_label
;; ETH_R_RETURN name
;; ETH_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
;; ETH_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name, no_buffer
;; ETH_W_WRITE_in_AX_CX_SI_DI_ES_const_BX_BP_ES name
;; ETH_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES name
;; ETH_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
;;
;; Variables Provided by this module (READ ONLY!!!!)
;;
;; eth_&name&_declared 1 if this module is declared
;; eth_&name&_address The hardware address
;; eth_&name&_mtu The maximum transmission unit
;;
;;*****************************************************************************
;;*****************************************************************************
;; defs for ethernet structures
IP_TYPE = 0800h
SWAPPED_IP_TYPE = 0008h
ARP_TYPE = 0806h
SWAPPED_ARP_TYPE = 0608h
ether STRUC
ether_dst DB 6 DUP (0)
ether_src DB 6 DUP (0)
ether_type DW 0
ether ENDS
;;*****************************************************************************
;; data storage needed by this module
eth_data STRUC
eth_type_tab dw 256 dup (0)
eth_w_try db ?
eth_data ENDS
;;*****************************************************************************
;; ETH_DECLARE name, interface, task
;; creates a new data link object. 'name' is the name of this new
;; object. 'interface' is the name of the interface to that will provide
;; the low level services this module will need. 'task' is the name
;; of a task that we need
;;
ETH_DECLARE MACRO name, interface, task
.errb <task>
.DATA
eth_&name&_declared = 1
eth_&name&_interface = interface
eth_&name&_task = task
eth_&name&_address = if_&interface&_address
eth_&name&_mtu = 1500 ;; maximum transmission unit
global eth_&name&_data:eth_data
.CODE
global eth_&name&_continue:near
global eth_&name&_real_define:near
ENDM
;;*****************************************************************************
;; ETH_DEFINE name
;; ETH_DEFINE declare all the things that have to be defined in
;; every independantly assembled module. ETH declares those
;; things that need be be done only once (in particular memory allocation
;; and initialzation code). Every module including the one ETH_DEFINE
;; is in) must have a ETH_DELCARE.
;;
ETH_DEFINE MACRO name
call eth_&name&_real_define
ENDM
ETH_REAL_DEFINE MACRO name
local start, around
.errb <name>
ifdef eth_&name&_declared
.DATA
eth_&name&_data eth_data <> ;; create storage needed
.CODE
jmp around
start:
ETH_TASK name
;; this does NOT fall through
around:
eth_&name&_real_define:
mov AX, DS ;; initilize table
mov ES, AX
mov AX, offset eth_&name&_continue
mov DI, offset eth_&name&_data.eth_type_tab
mov CX, 256
rep
stosw
TASK_DEFINE %eth_&name&_task, start ;; start the task
RET
endif
ENDM
;;******************************************************************************
;; ETH_R_READ name, type, code_label
;; ETH_R_READ declares that code starting at 'code_label' should be
;; called whenever a packet with type 'type' is read from the IF.
;; The code is called with BX:ES pointing to the start of the packet
;; CX loaded with the length of the packet and AX loaded with the
;; type of the packet. The code should
;; execute ETH_R_RETURN when it is through.
;;
ETH_R_READ MACRO name, type, code_label
local jmp_entry
.errb <code_label>
jmp_entry = eth_&name&_data.eth_type_tab+2*((type / 256) xor (type mod 256))
mov word ptr jmp_entry, offset code_label
ENDM
;;******************************************************************************
;; ETH_R_CONT_in_BX_CX_ES name, ok
;; ETH_R_CONT determines if the packet returned by R_READ in BX:ES
;; of length CX is continuous. If it is it jumps to 'ok' otherwise
;; it just returns
;;
ETH_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
.errb <ok>
IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES %eth_&name&_interface, ok
ENDM
;;******************************************************************************
;; ETH_R_RETURN
;; ETH_R_RETURN should be called at the end of the read code to signal
;; that the read code is finished with the packet read in
;;
ETH_R_RETURN MACRO name
.errb <name>
jmp eth_&name&_continue
ENDM
;;******************************************************************************
;; ETH_W_ACCESS_in_CX_out_DI_ES name, no_buffer
;; ETH_W_ACCESS returns a pointer to an output buffer for a (network)
;; packet. The pointer is returned in DI:ES. If the output buffer is
;; busy, this routine jump to 'no_buffer'. The buffer return will
;; be at least min(CX, 1500) bytes long
;;
ETH_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP MACRO name, no_buffer
.errb <no_buffer>
add CX, size ether
IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP %eth_&name&_interface, no_buffer
sub CX, size ether
add DI, size ether ;; make it point to the Data part
ENDM
;;******************************************************************************
;; ETH_W_WRITE_in_AX_CX_SI_DI_ES name, type
;; ETH_W_WRITE actually signals the link layer to write a packet to the
;; network. The packet is assumed to be in the buffer returned by
;; ETH_W_ACCESS. CX is the length of the packet to send. SI:DS holds
;; is a pointer to the hardware destination address. AX is the
;; type code of the ethernet packet to send.
;; DI:ES MUST point be the pointer returned by W_ACCESS_out_DI_ES
;;
ETH_W_WRITE_in_AX_CX_SI_DI_ES_const_BX_BP_ES MACRO name
local size_ok
.errb <name>
add CX, size ether
cmp CX, 60
jae size_ok
mov CX, 60
size_ok:
sub DI, size ether
movsw
movsw
movsw
mov SI, offset eth_&name&_address
movsw
movsw
movsw
stosw
IF_W_WRITE_in_CX_const_BX_BP_ES %eth_&name&_interface
ENDM
;;******************************************************************************
;; ETH_IS_BROADCAST_in_BX_ES name
;; ETH_IS_BROADCAST_in_BX_ES determines if the packet pointed to
;; by BX:ES is a broadcast and sets the zero flag if it is NOT a
;; broadcast
;;
ETH_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES MACRO name
.errb <name>
mov SI, BX
sub SI, size ether
test byte ptr ES:[SI], 80H
ENDM
;;******************************************************************************
;; ETH_COPY_in_CX_SI_DI_ES_out_SI_DI interface
;; ETH_COPY_in_CX_SI_DI_ES copies a packet from the input buffer (pointed
;; to by SI and the segement register given in IF_DECLARE) to an output
;; buffer (pointed to by DI and dest_reg) of length CX. It assumes the
;; output buffer is contiguous. (and the caller shouldn't care if the
;; input buffer is contiguous) COPY updates the pointers SI and DI
;; to the end of the packet, and COPY could be called again if CX is not
;; the total packet length (Note that CX MUST be even if you care about
;; SI, and DI being updated properly)
;;
ETH_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
.errb <name>
IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES %eth_&name&_interface
ENDM
;;******************************************************************************
;; ETH_TASK is the read task that reads the next packet from the interface
;; and dispatches it to the next higher protocol layer
;;
ETH_TASK MACRO name
local done
.errb <name>
IF_R_ACCESS_out_BX_CX_ES %eth_&name&_interface, done
mov AX, word ptr ES:[BX+ether_type]
add BX, size ether
sub CX, size ether
xor DX, DX ;; compute hash function
mov DL, AH
xor DL, AL
shl DX, 1
mov SI, DX ;;assume perfect hash function
jmp [SI+eth_&name&_data.eth_type_tab]
eth_&name&_continue:
IF_R_FREE_const_BX_CX_BP_SI_DI_ES %eth_&name&_interface
done:
TASK_RETURN %eth_&name&_task
ENDM